<template>
  <div class="image-viewer-page">
    <el-card class="image-viewer-card">
      <template #header>
        <div class="card-header">
          <h2>超声图像查看器</h2>
          <el-button @click="goBack" type="primary" plain>返回患者列表</el-button>
        </div>
      </template>
      
      <div class="image-viewer-container">
        <!-- 图像展示区域 -->
        <div class="image-container">
          <div class="image-placeholder" v-if="!imageData.ImageTrackList.length">
            <div class="placeholder-content">
              <el-icon :size="48" color="#c0c4cc"><Picture /></el-icon>
              <p class="placeholder-text">暂无图像数据</p>
            </div>
          </div>
          <canvas 
            v-show="imageData.ImageTrackList.length"
            ref="imageCanvas"
            class="image-canvas"
          ></canvas>
        </div>
        
        <!-- 帧数控制区域 -->
        <div class="frame-controls">
          <div class="frame-info">
            <span>帧数: {{ imageData.currentFrame }} / {{ imageData.frames }}</span>
          </div>
          
          <div class="frame-progress">
            <el-slider
              v-model="imageData.currentFrame"
              :min="1"
              :max="imageData.frames"
              :step="1"
              @change="onFrameChange"
              show-input
              show-input-controls
            />
          </div>
          
          <div class="navigation-buttons">
            <el-button 
              @click="prevFrame" 
              :disabled="imageData.currentFrame <= 1"
              circle
            >
              <el-icon><ArrowLeft /></el-icon>
            </el-button>
            
            <el-button 
              @click="togglePlay"
              :type="isPlaying ? 'danger' : 'primary'"
              circle
            >
              <el-icon><component :is="isPlaying ? VideoPause : VideoPlay" /></el-icon>
            </el-button>
            
            <el-button 
              @click="nextFrame" 
              :disabled="imageData.currentFrame >= imageData.frames"
              circle
            >
              <el-icon><ArrowRight /></el-icon>
            </el-button>
          </div>
        </div>
        
        <!-- 患者信息 -->
        <div class="patient-info" v-if="patientData">
          <el-descriptions title="患者信息" :column="4" border>
            <el-descriptions-item label="患者ID">{{ patientData.id }}</el-descriptions-item>
            <el-descriptions-item label="姓名">{{ patientData.name }}</el-descriptions-item>
            <el-descriptions-item label="模态">{{ patientData.modality }}</el-descriptions-item>
            <el-descriptions-item label="检查日期">{{ patientData.studyDate }}</el-descriptions-item>
          </el-descriptions>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElCard, ElButton, ElIcon, ElImage, ElSlider, ElDescriptions, ElDescriptionsItem } from 'element-plus'
import { Picture, ArrowLeft, ArrowRight, VideoPlay, VideoPause } from '@element-plus/icons-vue'
import { api } from '@/utils/api'

const route = useRoute()
const router = useRouter()

// Canvas 引用
const imageCanvas = ref(null)
const imageCache = new Map() // 图像缓存
let playInterval = null // 播放定时器

// 图像数据
const imageData = reactive({
  patientId: '',
  frames: 24,
  currentFrame: 1,
  ImageTrackList: []
})

// 播放状态
const isPlaying = ref(false)

// 患者信息
const patientData = ref(null)

// 获取患者图像数据
const fetchImage = async () => {
  try {
    // 从路由参数获取患者ID
    const patientId = route.params.patientId || 'P001'
    imageData.patientId = patientId

    console.log("获取患者图像数据:", patientId)
    
    // 模拟获取患者信息
    patientData.value = {
      id: patientId,
      name: '张三',
      modality: 'US',
      studyDate: '2023-05-15'
    }    
    // 获取图像数据
    const response = await api.getPatientImages(patientId) 
    console.log("获取患者图像数据响应:", response)
 
    imageData.ImageTrackList = response.extracted_files
    imageData.frames = response.extracted_files.length
    
    // 预加载第一帧图像
    if (imageData.ImageTrackList.length > 0) {
      await loadImageToCanvas(0)
    }
  } catch (error) {
    console.error('获取图像数据失败:', error)
  }
}

// 在 canvas 上绘制图像
const drawImageOnCanvas = (img) => {
  if (!imageCanvas.value) return
  
  const canvas = imageCanvas.value
  const ctx = canvas.getContext('2d')
  
  // 设置canvas尺寸为图像原始尺寸，但限制最大宽度为800px
  const maxWidth = 800
  const maxHeight = 600
  let displayWidth = img.width
  let displayHeight = img.height
  
  // 如果图像宽度超过最大宽度，则按比例缩放
  if (img.width > maxWidth) {
    const ratio = maxWidth / img.width
    displayWidth = maxWidth
    displayHeight = img.height * ratio
  }
  
  // 如果图像高度超过最大高度，则按比例缩放
  if (displayHeight > maxHeight) {
    const ratio = maxHeight / displayHeight
    displayHeight = maxHeight
    displayWidth = displayWidth * ratio
  }
  
  // 设置canvas的显示尺寸
  canvas.width = displayWidth
  canvas.height = displayHeight
  
  // 清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  
  // 居中绘制图像
  ctx.drawImage(img, 0, 0, displayWidth, displayHeight)
}

// 加载图像并在 canvas 上绘制
const loadImageToCanvas = async (frameIndex) => {
  if (frameIndex < 0 || frameIndex >= imageData.ImageTrackList.length) return
  
  const imageName = imageData.ImageTrackList[frameIndex]
  const imageUrl = `http://localhost:8000/dicom-img/${imageName}`
  
  // 检查缓存中是否已有图像
  if (imageCache.has(imageUrl)) {
    drawImageOnCanvas(imageCache.get(imageUrl))
    return
  }
  
  // 创建新的图像对象
  return new Promise((resolve) => {
    const img = new Image()
    img.crossOrigin = 'anonymous' // 处理跨域问题
    
    img.onload = () => {
      // 缓存图像
      imageCache.set(imageUrl, img)
      // 绘制图像
      drawImageOnCanvas(img)
      resolve()
    }
    
    img.onerror = () => {
      console.error('图像加载失败:', imageUrl)
      resolve()
    }
    
    img.src = imageUrl
  })
}

// 上一帧
const prevFrame = async () => {
  if (imageData.currentFrame > 1) {
    imageData.currentFrame--
    await loadImageToCanvas(imageData.currentFrame - 1)
  }
}

// 下一帧
const nextFrame = async () => {
  if (imageData.currentFrame < imageData.frames) {
    imageData.currentFrame++
    await loadImageToCanvas(imageData.currentFrame - 1)
  }
}

// 切换播放状态
const togglePlay = () => {
  isPlaying.value = !isPlaying.value
  
  if (isPlaying.value) {
    startPlayback()
  } else {
    stopPlayback()
  }
}

// 添加一个标志位来区分是用户手动操作还是自动播放
let isUserInteraction = true

// 监听当前帧变化，仅在用户手动拖动滑块时停止播放
watch(() => imageData.currentFrame, () => {
  // 只有在用户手动操作时才停止播放
  if (isPlaying.value && isUserInteraction) {
    stopPlayback()
    isPlaying.value = false
  }
  // 重置标志位
  isUserInteraction = true
})

// 修改onFrameChange函数，设置用户交互标志
const onFrameChange = async (value) => {
  isUserInteraction = true
  imageData.currentFrame = value
  await loadImageToCanvas(value - 1)
}

// 开始播放
const startPlayback = () => {
  // 如果已经到达最后一帧，则从头开始
  if (imageData.currentFrame >= imageData.frames) {
    isUserInteraction = false
    imageData.currentFrame = 1
    loadImageToCanvas(0)
  }
  
  // 设置定时器，每200ms切换一帧
  playInterval = setInterval(() => {
    if (imageData.currentFrame < imageData.frames) {
      isUserInteraction = false
      imageData.currentFrame++
      loadImageToCanvas(imageData.currentFrame - 1)
    } else {
      // 到达最后一帧时循环播放，从第一帧开始
      isUserInteraction = false
      imageData.currentFrame = 1
      loadImageToCanvas(0)
    }
  }, 200)
}

// 停止播放
const stopPlayback = () => {
  if (playInterval) {
    clearInterval(playInterval)
    playInterval = null
  }
}

// 返回患者列表
const goBack = () => {
  // 停止播放
  stopPlayback()
  router.push('/patients')
}

// 组件卸载前清理
onBeforeUnmount(() => {
  stopPlayback()
  imageCache.clear()
})

// 组件挂载时获取数据
onMounted(() => {
  fetchImage()
})
</script>

<style scoped>
.image-viewer-page {
  padding: 20px;
  background-color: #f5f5f5;
  min-height: calc(100vh - 60px);
}

.image-viewer-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header h2 {
  margin: 0;
  color: #303133;
}

.image-viewer-container {
  padding: 20px 0;
}

.image-container {
  text-align: center;
  margin-bottom: 30px;
}

.image-placeholder {
  width: 100%;
  max-width: 800px;
  height: 500px;
  background-color: #f0f0f0;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  border-radius: 8px;
}

.placeholder-content {
  text-align: center;
}

.placeholder-text {
  margin: 10px 0 0 0;
  color: #909399;
  font-size: 16px;
}

.image-canvas {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  background-color: #000;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .image-placeholder,
  .image-canvas {
    height: 300px;
  }
  
  .image-canvas {
    max-width: 100%;
  }
}

@media (max-width: 480px) {
  .image-placeholder,
  .image-canvas {
    height: 200px;
  }
}

.frame-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
  margin-bottom: 30px;
  flex-wrap: wrap;
}

.frame-info {
  font-size: 16px;
  font-weight: bold;
  min-width: 120px;
  text-align: center;
  color: #303133;
}

.frame-progress {
  flex: 1;
  max-width: 600px;
}

.navigation-buttons {
  display: flex;
  gap: 10px;
}

.patient-info {
  margin-top: 30px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .image-viewer-page {
    padding: 10px;
  }
  
  .image-placeholder,
  .image-canvas {
    height: 300px;
  }
  
  .frame-controls {
    flex-direction: column;
    gap: 15px;
  }
  
  .frame-progress {
    max-width: 100%;
    width: 100%;
  }
  
  .card-header {
    flex-direction: column;
    gap: 15px;
    text-align: center;
  }
}
</style>